FUNCTION_BLOCK LCB_GenericDrive
TITLE = 'LCB_GenericDrive'

// Functionblock for a userdefined Application
// The implementation is independant of the used bussystem (Profinet / Profibus)
//
// Used S7 Systemfunctions 
// SFC14 (DPRD_DAT)
// SFC15 (DPWR_DAT)
//
// Versionshistory:
// 1.0 Ersterstellung E.Dittmann


AUTHOR : 'Lenze'
Family : 'LCB'
Version : '1.0'
Name: 'GenDrive'
// KNOW_HOW_PROTECT


CONST
    Range := 4; // Count of wors from / to the drive 
END_CONST

VAR_INPUT
    iFirstPeripherieADR:    INT;                                    // Peripheral adress of the drive (Hardwareconfig S7)
    awTxData:                ARRAY[1..Range] OF WORD;               // Word Array, Controldata for drive
    xEnableInternalControl: BOOL;                                   // Enable internal drivecontrol with variabletable
END_VAR

VAR_OUTPUT
    awRxData:                ARRAY[1..Range] OF WORD;               // Word Array, Statusdata from drive
    xInternalControlActive: BOOL;                                   // Internal control active
    xCommunicationOK:       BOOL;                                   // Communication OK
    xError:                 BOOL;                                   // Error
    iReadError:             INT;                                    // Errorcode SFC14 
    iWriteError:            INT;                                    // Errorcode SFC15 
END_VAR

VAR_IN_OUT

END_VAR


VAR
    wFirstPeripherieADR:    WORD;                                   
    scInternalCtrl:         STRUCT                                  
                                b8:     BOOL;
                                b9:     BOOL;
                                b10:    BOOL;
                                b11:    BOOL;
                                b12:    BOOL;
                                b13:    BOOL;
                                b14:    BOOL;
                                b15:    BOOL;
                                b0:     BOOL;
                                b1:     BOOL;
                                b2:     BOOL;
                                b3:     BOOL;
                                b4:     BOOL;
                                b5:     BOOL;
                                b6:     BOOL;
                                b7:     BOOL;
                                awInt:  ARRAY[2..Range] OF WORD;
                            END_STRUCT;
                            
    scInternalState:        STRUCT                                  
                                b8:     BOOL;
                                b9:     BOOL;
                                b10:    BOOL;
                                b11:    BOOL;
                                b12:    BOOL;
                                b13:    BOOL;
                                b14:    BOOL;
                                b15:    BOOL;
                                b0:     BOOL;
                                b1:     BOOL;
                                b2:     BOOL;
                                b3:     BOOL;
                                b4:     BOOL;
                                b5:     BOOL;
                                b6:     BOOL;
                                b7:     BOOL;
                                awInt:  ARRAY[2..Range] OF WORD;
                            END_STRUCT;

END_VAR

BEGIN

wFirstPeripherieADR:= INT_TO_WORD(iFirstPeripherieADR);             
iReadError:=0;
iWriteerror:=0;

IF xEnableInternalControl THEN                                      // Interne Steuerung des Reglers
    xInternalControlActive:=True;
    iReadError:= DPRD_DAT(
                        LADDR := wFirstPeripherieADR, 
                        RECORD := scInternalState ); 
                         
    iWriteError:=DPWR_DAT(
                        LADDR := wFirstPeripherieADR, 
                        RECORD := scInternalCtrl ); 
 ELSE                                                               // Steuerung des Reglers über Eingangsvariablen des Bausteins
    xInternalControlActive:=False;
    iReadError:= DPRD_DAT(
                        LADDR := wFirstPeripherieADR, 
                        RECORD := awRxData ); 
   
    iWriteError:=DPWR_DAT(
                         LADDR := wFirstPeripherieADR, 
                        RECORD := awTxData ); 
END_IF;
                                                                    // Setzen der Stausvariablen
IF (iReadError <> 0) OR (iWriteError <> 0) THEN
    xError:= true;
    xCommunicationOK:=false;
ELSE
    xError:= false;
    xCommunicationOK:=True;
END_IF;
     
END_FUNCTION_BLOCK